package com.hainingtong.core.shiro.realm;


import com.hainingtong.core.entity.SysAuth;
import com.hainingtong.core.entity.SysUser;
import com.hainingtong.core.service.UserService;
import com.hainingtong.core.shiro.token.CustomUsernamePasswordToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

@Slf4j
public class UsernamePasswordRealm extends AuthorizingRealm {

    @Autowired
    UserService userService;

    /**
     * 自定义匹配密码的方法
     */
    public UsernamePasswordRealm() {
        this.setCredentialsMatcher(new CredentialsMatcher() {
            @Override
            public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) {
                return BCrypt.checkpw(authenticationToken.getCredentials().toString(), authenticationInfo.getCredentials().toString());
            }
        });
    }

    /**
     * 只处理对应类型的认证
     *
     * @param token
     * @return 如果是对应的类型就返回true，表示会执行doGetAuthorizationInfo获取用户信息用于认证；false就跳过当前realm
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof CustomUsernamePasswordToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 由于我们每个需要权限的接口都需要使用 jwt 认证，所以权限只需要在 jwtRealm里面赋予就可以了
        return null;
    }

    /**
     * @Description 认证配置类
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        if (!StringUtils.hasText(authenticationToken.getPrincipal().toString())) {
            return null;
        }
        CustomUsernamePasswordToken token = (CustomUsernamePasswordToken)authenticationToken;
        //获取用户信息
        String principal = token.getPrincipal();
        SysAuth auth = userService.findAuthByPrincipalAndType(principal, token.getLoginType().name());
        // 没找到数据或者登录类型不一样 就直接返回
        if(auth==null || !auth.getLoginType().equals(token.getLoginType())){
            return null;
        }

        SysUser user = userService.findUserById(auth.getUserId());
        if(user == null){
            return null;
        }

        return new SimpleAuthenticationInfo(auth.getPrincipal(), auth.getCredential(), getName());
    }
}
